//
// Created by Administrator on 2023-03-21.
//

#include "Texture.h"
#include "LogUtil.h"
#include <stdlib.h>
//引入stb_image
#define STB_IMAGE_IMPLEMENTATION
extern "C"{
#include "stb_image.h"
}

Texture::Texture()
{

}

Texture::~Texture()
{
    if (mProgram)
    {
        //删除Program
        glUtil.DeleteProgram(mProgram);
    }
}

void Texture::Init(AAssetManager*  pManager,const char* vShaderFileName,const char* fShaderFileName)
{
    //顶点着色器
    AAsset* vFile = AAssetManager_open(pManager,vShaderFileName, AASSET_MODE_BUFFER);
    size_t vShaderSize = AAsset_getLength(vFile);
    char* vContentBuff = (char*)malloc(vShaderSize);
    AAsset_read(vFile, vContentBuff, vShaderSize);
    LOGD("VSHADERS: %s",vContentBuff);
    AAsset_close(vFile);

    //片元着色器
    AAsset* fFile = AAssetManager_open(pManager,fShaderFileName, AASSET_MODE_BUFFER);
    size_t fShaderSize = AAsset_getLength(fFile);
    char* fContentBuff = (char*)malloc(fShaderSize);
    AAsset_read(fFile, fContentBuff, fShaderSize);
    LOGD("FSHADERS: %s",fContentBuff);
    AAsset_close(fFile);

    mProgram = glUtil.CreateProgram(vContentBuff, fContentBuff, mVertexShader, mFragmentShader);

    textureLocation = glGetUniformLocation(mProgram,"s_TextureMap");
    uValueLocation = glGetUniformLocation(mProgram,"uValue");

    //释放
    free(vContentBuff);
    free(fContentBuff);
}

void Texture::InitTexture(const char* textureFileName){
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1,&m_texID);//产生纹理索引
    glBindTexture(GL_TEXTURE_2D,m_texID);//绑定纹理索引，之后的操作都针对当前纹理索引

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//指当纹理图象被使用到一个大于它的形状上时
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//指当纹理图象被使用到一个小于或等于它的形状上时
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    // 加载并生成纹理
    unsigned char *data = stbi_load(textureFileName, &width, &height, &nrChannels, 0);
    if (data)
    {
        if(nrChannels == 3){
            //字节对齐
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        } else if(nrChannels == 4){
            //字节对齐
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        }
    }
    stbi_image_free(data);

}

void Texture::Draw(int textureId)
{
    //顶点数据
    GLfloat vVertices[] = {
            1.0f, 1.0f, 0.0f,  // Position 0
            -1.0f,  1.0f, 0.0f,  // Position 1
            -1.0f, -1.0f, 0.0f,  // Position 2
            1.0f, -1.0f, 0.0f,  // Position 3
    };

    //绘制Texture纹理位置信息
    GLfloat textureCoords[] = {
            0.0f,  0.0f,        // TexCoord 0
            0.0f,  1.0f,        // TexCoord 1
            1.0f,  1.0f,        // TexCoord 2
            1.0f,  0.0f         // TexCoord 3
    };

    //绘制顶点的信息
    GLushort indices[] = { 0, 1, 2, 0, 2, 3 };


    if(mProgram == 0)
        return;

    glUseProgram(mProgram);


    glVertexAttribPointer (0, 3, GL_FLOAT,
                           GL_FALSE, 3 * sizeof (GLfloat), vVertices);

    glVertexAttribPointer (1, 2, GL_FLOAT,
                           GL_FALSE, 2 * sizeof (GLfloat), textureCoords);

    glEnableVertexAttribArray (0);
    glEnableVertexAttribArray (1);


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureId);

    glUniform1i(textureLocation, 0);

    uValue += 0.015;
    glUniform1f(uValueLocation, uValue);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
